home *** CD-ROM | disk | FTP | other *** search
- /**
- ** VESA.C ---- VESA compatible paging routines
- **
- ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
- ** Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
- ** Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
- **
- ** This file is distributed under the terms listed in the document
- ** "copying.dj", available from DJ Delorie at the address above.
- ** A copy of "copying.dj" should accompany this file; if not, a copy
- ** should be available from where this file was obtained. This file
- ** may not be distributed without a verbatim copy of "copying.dj".
- **
- ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
- ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **/
-
- int VESA_win_write = 0; /* VESA window index of the writable page */
- int VESA_win_read = (-1); /* VESA window index of the readable page */
-
- void far paging_routine(void)
- {
- return;
- }
-
- void far VESA_paging_routine(void)
- {
- asm push ds;
- asm push es;
- asm mov cl,BYTE PTR cs:[driver_header.page_gran_shift];
- asm mov dl,al;
- asm xor dh,dh;
- asm shl dx,cl; /* DX: write window (A or B) index */
- asm mov al,ah;
- asm xor ah,ah;
- asm shl ax,cl; /* AX: read window index */
- asm mov bx,WORD PTR cs:[VESA_win_write]; /* index (A or B) of write window */
- asm cmp bx,(-1); /* set it ? */
- asm je set_read_window;
- asm push ax; /* save read window */
- asm mov ax,0x4f05;
- asm call DWORD PTR cs:[driver_header.VESA_paging_fnc];
- asm pop ax;
- set_read_window:
- asm mov bx,WORD PTR cs:[VESA_win_read]; /* index (A or B) of read window */
- asm cmp bx,(-1); /* set it ? */
- asm je paging_done;
- asm mov dx,ax;
- asm mov ax,0x4f05;
- asm call DWORD PTR cs:[driver_header.VESA_paging_fnc];
- paging_done:
- asm pop es;
- asm pop ds;
- asm mov al,8; /* reconfig GR CTRL port for mask writes */
- asm mov dx,0x3ce; /* GRX expects it in 16 color modes, and */
- asm out dx,al; /* the paging func may have changed it */
- return;
- }
-
- int setup_VESA_paging(GrModeEntry *md)
- {
- ModeInfoBlock *mb = VESAgetModeInfo(md->mode.vdr.BIOS_mode);
- int winsize,wingran,Aattr,Battr,Sdiff;
-
- if(!mb || !(mb->ModeAttributes & MODE_ISGRAPHICS)) {
- VESA_win_read = (-1);
- VESA_win_write = (-1);
- driver_header.VESA_paging_fnc = 0L;
- driver_header.paging_routine = FP_OFF(paging_routine);
- return(GRD_NO_RW);
- }
-
- /* size and granularity must be pwr of 2! */
- for(winsize = 0; (1 << winsize) < mb->WinSize; winsize++) ;
- for(wingran = 0; (1 << wingran) < mb->WinGranularity; wingran++) ;
- if((1 << winsize) != mb->WinSize) return(-1);
- if((1 << wingran) != mb->WinGranularity) return(-1);
-
- /* check window attributes */
- Aattr = mb->WinAAttributes;
- Battr = mb->WinBAttributes;
- Sdiff = mb->WinBSegment - mb->WinASegment;
- Aattr &= (Aattr & WIN_SUPPORTED) ? (WIN_READABLE | WIN_WRITABLE) : 0;
- Battr &= (Battr & WIN_SUPPORTED) ? (WIN_READABLE | WIN_WRITABLE) : 0;
-
- /* cases with two adjacent split R/W pages (ATI) */
- if((Aattr == (WIN_READABLE | WIN_WRITABLE)) &&
- (Battr == (WIN_READABLE | WIN_WRITABLE)) &&
- (Sdiff == ((1024 / 16) << winsize))) {
- driver_header.wr_page_start = mb->WinASegment;
- driver_header.rd_page_start = mb->WinBSegment;
- VESA_win_write = 0;
- VESA_win_read = 1;
- }
- else if((Aattr == (WIN_READABLE | WIN_WRITABLE)) &&
- (Battr == (WIN_READABLE | WIN_WRITABLE)) &&
- (Sdiff == ((-1024 / 16) << winsize))) {
- driver_header.wr_page_start = mb->WinBSegment;
- driver_header.rd_page_start = mb->WinASegment;
- VESA_win_write = 1;
- VESA_win_read = 0;
- }
-
- /* cases with one full R and one full W page (Tseng 4000) */
- else if((Aattr & WIN_READABLE) &&
- (Battr & WIN_WRITABLE) &&
- (Sdiff == 0)) {
- driver_header.wr_page_start = mb->WinBSegment;
- driver_header.rd_page_start = mb->WinASegment;
- VESA_win_write = 1;
- VESA_win_read = 0;
- }
- else if((Aattr & WIN_WRITABLE) &&
- (Battr & WIN_READABLE) &&
- (Sdiff == 0)) {
- driver_header.wr_page_start = mb->WinASegment;
- driver_header.rd_page_start = mb->WinBSegment;
- VESA_win_write = 0;
- VESA_win_read = 1;
- }
-
- /* single page cases (Trident) */
- else if(Aattr == (WIN_WRITABLE | WIN_READABLE)) {
- driver_header.wr_page_start = mb->WinASegment;
- driver_header.rd_page_start = 0xffff;
- VESA_win_write = 0;
- VESA_win_read = (-1);
- }
- else if(Battr == (WIN_WRITABLE | WIN_READABLE)) {
- driver_header.wr_page_start = mb->WinBSegment;
- driver_header.rd_page_start = 0xffff;
- VESA_win_write = 1;
- VESA_win_read = (-1);
- }
- /* cannot use the paging scheme of this card */
- else return(-1);
-
- /* setup header variables */
- driver_header.page_size_shift = winsize - 2; /* in 4kByte units */
- driver_header.page_gran_shift = winsize - wingran;
- driver_header.line_offset = mb->BytesPerScanLine;
- driver_header.VESA_paging_fnc = mb->WinFuncPtr;
- driver_header.paging_routine = FP_OFF(VESA_paging_routine);
- return((VESA_win_read == (-1)) ? GRD_NO_RW : GRD_RW_64K);
- }
-